<?php

namespace App\Http\Controllers\Api\Ncdh;

use App\Http\Controllers\Controller;
use App\Models\Ncdh\NcdhBettingSort;
use App\Models\Ncdh\NcdhIssue;
use App\Models\Ncdh\NcdhOrderDetailLog;
use App\Models\Ncdh\NcdhOrderLog;
use App\Models\Ncdh\NcdhPayLog;
use App\UserCoinLog;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class NcdhController extends Controller
{
    protected $wechat;

    public function __construct()
    {
        $this->wechat = app('wechat');
    }
    

    /**
     * @function:获取当前一期用户下注汇总详情
     * @return \Illuminate\Http\JsonResponse
     */
    public function getRunningIssue()
    {
        $user = auth()->user();

        //获取当前一期开奖信息
        $currentIssue = NcdhIssue::getRunningIssue();

        //获取用户当期下注种类汇总金额
        $paySumInfo = NcdhOrderDetailLog::getUserOrderDetailSumByType($currentIssue['id'], $user->id);

        return response()->json([
            'code' => 0,
            'msg' => 'success',
            'data' => [
                'id' => $currentIssue['id'],
                'openAfter' => $currentIssue['openAfter'],
                'paySumInfo' => $paySumInfo,    //下单金额分类汇总
                'nickname' => $user->nickname,  //用户昵称
                'avatar' => $user->avatar,      //用户头像
                'XYB' => $user->XYB,        //用户小妖币
            ],
        ]);
    }

    /**
     * @function 下单
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function doPay(Request $request)
    {
        
        //数据结构
        //$payList   = [
        //    'type1' => 'gold1',
        //    'type2' => 'gold2',
        //    'type3' => 'gold3',
        //];
        $payList = $request->input('payList');      //投注类型
        $issue = (int)$request->input('issue');      //期号

        $goldSum = 0;  //下单总额

        //绝对值处理
        foreach ($payList as $type => $gold) {
            $payList[$type] = abs($gold);
            $goldSum += $payList[$type];
        }

        //获取用户实例
        $user = auth()->user();

        //是否已封盘
        $currentIssue = NcdhIssue::getRunningIssue();

        //当前一期是否已经封盘
        if ($issue !== $currentIssue['id'] || ($currentIssue['openAfter'] <= 1)) {
            return response()->json([
                'code' => 1,
                'msg' => '已封盘'
            ]);
        }

        //判断用户余额是否充足
        if ($user->XYB < $goldSum) {
            return response()->json([
                'code' => 1,
                'msg' => '用户余额不足'
            ]);
        }

        //每个用户每期只能购买500
        if ($goldSum >= 500) {
            return response()->json([
                'code' => 1,
                'msg' => '每个用户每期只能投50000小妖币哦'
            ]);
        }

        //下单金额不能为0
        if ($goldSum == 0) {
            return response()->json([
                'code' => 1,
                'msg' => '下单金额有误'
            ]);
        }


        // 限定操作频次
        $redis = new \Redis();
        $redis->connect(env('REDIS_HOST'), env('REDIS_PORT'));
        $redis->auth(env('REDIS_PASSWORD'));

        $key = "ncdh:handle:$user->id";
        if (!$redis->set($key, 'Y', array('nx', 'px' => 1000))) {
            return response()->json([
                'code' => 1,
                'msg' => '您的操作过于频繁，请稍后再试'
            ]);
        }

        //增加历史获利的统计
        if (NcdhPayLog::where('user_id', $user->id)->sum('add_XYB') >= 500) {

            //发出警报
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, "http://sms-api.luosimao.com/v1/send_batch.json");
            curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 8);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt($ch, CURLOPT_HEADER, FALSE);
            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
            curl_setopt($ch, CURLOPT_USERPWD, 'api:key-5145112f10b704bbd5592f80402c77b5');
            curl_setopt($ch, CURLOPT_POST, TRUE);
            curl_setopt($ch, CURLOPT_POSTFIELDS, array('mobile_list' => '13726873311', 'message' => '你好，发现异常情况。项目：农场大亨，UID：' . $user->id . '，描述：用户通过游戏获利超过500元。【小妖传媒】'));
            curl_exec($ch);

            return response()->json([
                'code' => 1,
                'msg' => '请勿频繁操作',
            ]);
        }

        $code = 0;
        $msg = '下单成功';

        //下单
        try {

            $now = time();

            //【重要】下面重复提交限制使用了第二个参数$now
            $key = $user->id . '-' . $now;

            //记录下单记录
            try {

                $orderLogModel = new NcdhOrderLog();
                $orderLogModel->user_id = $user->id;
                $orderLogModel->gold = $goldSum;
                $orderLogModel->add_time = $now;
                $orderLogModel->update_time = $now;
                $orderLogModel->issue = $currentIssue['id'];
                $orderLogModel->key = $key;
                $orderLogModel->pay_list = json_encode($payList);
                $orderLogModel->save();

                $orderLogId = $orderLogModel->id;

            } catch (\Exception $e) {
                throw new \Exception('下单错误，请勿重复提交', 1);
            }

            //查询上一次下单时间
            $preOrderLogKey = NcdhOrderLog::where('id', '<', $orderLogId)->where('user_id', $user->id)->orderBy('id', 'desc')->limit(1)->value('key');

            if (!empty($preOrderLogKey)) {

                $keyParts = explode('-', $preOrderLogKey);
                $preOrderAddTime = $keyParts[1];

                if ($now - $preOrderAddTime < config('ncdh.time_limit')) {  //上一次下单时间比下单停顿时间短，认为并发
                    NcdhOrderLog::find($orderLogId)->forceDelete();
                    throw new \Exception("请勿重复提交", 1);
                }
            }

            DB::beginTransaction();

            $userXYB = $user->XYB;

            //记录扣款日志
            $payLogModel = new NcdhPayLog();
            $payLogModel->user_id = $user->id;
            $payLogModel->from_XYB = $userXYB;
            $payLogModel->add_XYB = -$goldSum;
            $payLogModel->to_XYB = $userXYB - $goldSum;
            $payLogModel->issue = $currentIssue['id'];
            $payLogModel->order_id = $orderLogId;
            $payLogModel->add_time = $now;
            $payLogModel->update_time = $now;
            $payLogModel->save();

            //扣减用户余额
            //config/type.php    9 => '农场大亨下单'
            $key = '9-' . $user->id . '-' . -$goldSum . '-' . $now;
            //business表  9 => 农场大亨
            UserCoinLog::log(9, $user->id, UserCoinLog::TYPE_XYB, -$goldSum, '农场大亨下单消耗', $key);

            //用户玩游戏状态更新
            $user->update(['status' => DB::raw('status|4')]);

            if ($user->XYB < 0) {
                throw new \Exception('小妖币不足，请充值', 1);
            }

            //记录订单详情
            foreach ($payList as $type => $gold) {

                $orderDetailModel = new NcdhOrderDetailLog();
                $orderDetailModel->user_id = $user->id;
                $orderDetailModel->type = $type;
                $orderDetailModel->gold = $gold;
                $orderDetailModel->issue = $currentIssue['id'];
                $orderDetailModel->order_id = $orderLogId;
                $orderDetailModel->add_time = $now;
                $orderDetailModel->update_time = $now;
                $orderDetailModel->save();
            }

            DB::commit();

        } catch (\Exception $e) {

            DB::rollBack();
            $code = 1;
            $msg = $e->getMessage();
        }

        //获取用户当期投注种类信息汇总
        $paySumInfo = NcdhOrderDetailLog::getUserOrderDetailSumByType($currentIssue['id'], $user->id);

        return response()->json([
            'code' => $code,
            'msg' => $msg,
            'data' => [
                'id' => $currentIssue['id'],   //期号
                'openAfter' => $currentIssue['openAfter'],   //开奖时间
                'paySumInfo' => $paySumInfo,   //下注信息汇总
                'XYB' => $user->XYB,
            ],
        ]);

    }

    /**
     * @function 撤销下单
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function unPay(Request $request)
    {
        $user = auth()->user();
        $issue = $request->input('issue');

        if (empty($issue)) {
            return response()->json([
                'code' => 1,
                'msg' => '缺少期号参数'
            ]);
        }

        //获取当前一期开奖信息
        $currentIssue = NcdhIssue::getRunningIssue();

        //期号没记录
        if (empty($currentIssue['id']) || ($currentIssue['id'] != $issue)) {
            return response()->json([
                'code' => 1,
                'msg' => '该期没有正在进行中'
            ]);
        }

        //期号正在开奖中
        if ($currentIssue['openAfter'] <= 1) {
            return response()->json([
                'code' => 1,
                'msg' => '该期正在开奖中',
            ]);
        }

        //撤销购买
        $code = 0;
        $msg = '撤销成功';

        try {

            DB::beginTransaction();

            //获取订单详情
            $orderDetail = NcdhOrderDetailLog::getUserOrderDetail($issue, $user->id);

            //记录订单详情撤销
            $res = NcdhOrderDetailLog::where('issue', $currentIssue['id'])
                ->where('user_id', $user->id)->where('unpay', 0)
                ->update(['unpay' => 1]);

            if ($res) {
                throw new \Exception('撤销失败', 1);
            }

            //退还金额
            $now = time();
            foreach ($orderDetail as $orderItem) {

                $userXYB = $user->XYB;
                //记录奖励
                $payLogModel = new NcdhPayLog();
                $payLogModel->user_id = $user->id;
                $payLogModel->from_XYB = $userXYB;
                $payLogModel->add_XYB = $orderItem['gold'];
                $payLogModel->to_XYB = $userXYB + $orderItem['gold'];
                $payLogModel->issue = $currentIssue['id'];
                $payLogModel->order_id = $orderItem['order_id'];
                $payLogModel->add_time = $now;
                $payLogModel->update_time = $now;
                $payLogModel->save();

                //config/type.php    9 => '农场大亨下单'
                $key = '9-' . $user->id . '-' . $orderItem['order_id'] . '-' . $orderItem['type'] . '-' . $orderItem['gold'];

                //business表  9 => '农场大亨'
                UserCoinLog::log(9, $user->id, UserCoinLog::TYPE_XYB, $orderItem['gold'], '农场大亨撤销返还', $key);
            }

            DB::commit();

        } catch (\Exception $e) {

            DB::rollBack();
            Log::debug($e);
            $code = 1;
            $msg = '撤销失败';

        }

        //获取用户当期投注种类信息汇总
        $paySumInfo = NcdhOrderDetailLog::getUserOrderDetailSumByType($currentIssue['id'], $user->id);

        return response()->json([
            'code' => $code,
            'msg' => $msg,
            'data' => [
                'issue' => $currentIssue['id'],
                'openAfter' => $currentIssue['openAfter'],   //开奖时间
                'paySumInfo' => $paySumInfo,   //购买投注种类汇总
                'XYB' => $user->XYB,
            ],
        ]);
    }

    /**
     * 开奖结果查询接口
     */
    public function getIssueOpenResult(Request $request)
    {
        $issue = $request->input('issue');

        $user = auth()->user();
        $currentIssue = NcdhIssue::getRunningIssue();

        if (empty($issue)) {
            return response()->json([
                'code' => 1,
                'msg' => '缺少期号参数',
            ]);
        }

        $winType = NcdhIssue::getIssueWinType($issue);

        switch ($winType) {
            case 0:
                $code = 1;
                $msg = '该期正在进行中';
                break;
            case -1:
                $code = 1;
                $msg = '该期不存在';
                break;
            case -2:
                $code = 1;
                $msg = '该期正在开奖中';
                break;
            default:
                $code = 0;
                $msg = '开奖成功';
                break;
        }

        if ($code == 1) {
            return response()->json([
                'code' => $code,
                'msg' => $msg,

            ]);
        }
        //获取用户当期中奖金额
        $winGold = NcdhOrderDetailLog::getUserWinGold($issue, $user->id, $winType);

        return response()->json([
            'code' => $code,
            'msg' => $msg,
            'data' => [
                'id' => $currentIssue['id'],
                'openAfter' => $currentIssue['openAfter'],
                'XYB' => $user->XYB,
                'winType' => $winType,
                'winGold' => $winGold,
            ],
        ]);
    }

    /**
     * 创建下一期 @todo 临时接口
     */
    public function createNextIssue()
    {

        $code = 0;
        $msg = '创建下一期成功';
        $issue = NcdhIssue::createNextIssue();

        if (empty($issue)) {
            $code = 1;
            $msg = '创建下一期失败';
        }

        return response()->json([
            'code' => $code,
            'msg' => $msg,
            'data' => [
                'issue' => $issue
            ],
        ]);

    }

    /**
     * 获取最近中奖信息
     */
    public function getLatestWinInfo(Request $request)
    {
        $size = $request->input('size');

        $items = NcdhIssue::getLatestWinInfo($size);

        return response()->json([
            'code' => 0,
            'msg' => '获取最近中奖信息成功',
            'data' => $items,
        ]);
    }

    /**
     * 获取最近中奖详情（用户昵称、中奖类型、中奖金额）
     */
    public function getLatestWinDetail(Request $request)
    {
        $size = $request->input('size');

        $items = NcdhOrderDetailLog::getLatestWinDetail($size);

        return response()->json([
            'code' => 0,
            'msg' => '获取最近中奖详情成功',
            'data' => $items,
        ]);
    }

    public function get_rand()
    {
        $proArr=[
            '9'=>50,
            '10'=>50
        ];
        $result = '';
        //概率数组的总概率精度
        $proSum = array_sum($proArr);
        //概率数组循环
        foreach ($proArr as $key => $proCur) {
            $randNum = mt_rand(1, $proSum);             //抽取随机数
            if ($randNum <= $proCur) {
                $result = $key;                         //得出结果
                break;
            } else {
                $proSum -= $proCur;
            }
        }
        unset ($proArr);
        return $result;
    }
}
